#[derive(FromForm)]
struct GlobalVarsUpload {
    g_str: String
}

#[post("/library/upload_global_vars", data = "<form>")]
fn upload_global_vars(form: Form<GlobalVarsUpload>, _cookies: Cookies, state: State<MySqlDriver>) -> String {
    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        return "fail:无法建立数据库连接".to_string();
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        return "fail:无法获取数据库连接".to_string();
    }

    let g_str_hostr: HoString = HoString::copy_string(form.g_str.clone());
    let array1: Vec<HoString> = g_str_hostr.split_str("\"");
    let mut temp: Vec<String> = Vec::new();
    let mut except_vec: Vec<char> = Vec::new();
    except_vec.push('\'');
    except_vec.push('"');
    except_vec.push('\\');
    for array1_item in array1 {
        let array2: Vec<HoString> = array1_item.split_str("'");
        if array2.len() != 3 {
            return "fail:键值格式错误".to_string();
        }
        let id_result = array2.get(0).unwrap().to_string().parse::<usize>();
        if let Err(_) = id_result {
            return "fail:非法ID".to_string();
        }
        let id: usize = id_result.unwrap();
        let item1: HoString = array2.get(1).unwrap().clone();
        let item2: HoString = array2.get(2).unwrap().clone();
        if item1.contains_char_vec(except_vec.clone(), 0) == true ||
            item2.contains_char_vec(except_vec.clone(), 0) == true {
            return "fail:表单值不能包含引号和斜杠".to_string();
        }
        if temp.contains(&item1.to_string()) {
            return "fail:键不能有重复".to_string();
        } else {
            temp.push(item1.to_string());
        }
        if id == 0 {
            let sql: String = format!("INSERT INTO `global_var`(`global_key`, `global_value`) VALUES('{}', '{}')", item1.to_str(), item2.to_str());
            if let Err(_) = conn.exec_drop(sql.clone(), ()) {
                return "fail:无法提交键值".to_string();
            }
        } else {
            let sql: String = format!("UPDATE `global_var` SET `global_value` = '{}' WHERE `id` = {}", item2.to_str(), id);
            let _ = conn.exec_drop(sql.clone(), ());
        }
    }
    return "success:".to_string();
}

#[get("/edit_global")]
fn edit_global(cookies: Cookies, state: State<MySqlDriver>) -> Response<'static> {
    let mut res = Response::new();
    res.set_header(ContentType::HTML);

    // mod_id: String, 
    // mod_menu_open: String, 
    // sub_mod_id: String, 
    // page_title: String, 
    // title: String
    let header: String = get_header(
        "superadmin-mod".to_string(), 
        "superadmin-mod-menu-open".to_string(), 
        "superadmin-global-list".to_string(),
        "用户后台 - 网站全局".to_string(), 
        "网站全局".to_string(), &cookies,
        &state);

    let pool_result: Result<Pool, mysql::Error> = Pool::new(state.driver.as_str());
    let pool: Pool;
    if let Ok(p) = pool_result {
        pool = p;
    } else {
        res.set_sized_body(Cursor::new("无法建立数据库连接".to_string()));
        return res;
    }
    let conn_result: Result<PooledConn, mysql::Error> = pool.get_conn();
    let mut conn: PooledConn;
    if let Ok(c) = conn_result {
        conn = c;
    } else {
        res.set_sized_body(Cursor::new("无法获取数据库连接".to_string()));
        return res;
    }

    let sql: String = "SELECT `id`, `global_key`, `global_value` FROM `global_var` ORDER BY `id` ASC".to_string();
    let rows: Vec<Row> = conn.query(sql.clone()).unwrap();
    let mut tr: String = String::new();
    let mut array_js: String = String::new();
    for row in rows {
        let (id, global_key, global_value): (usize, String, String) = from_row(row);
        tr.push_str(format!("<div class=\"form-group\">
                        <label>{}</label>
                        <input type=\"text\" class=\"form-control\" id=\"global{}\" value=\"{}\">
                      </div>", global_key.as_str(), id, global_value.as_str()).as_str());
        array_js.push_str(format!("var i{} = [];\
                                  i{}['index'] = {};\
                                  i{}['id'] = {};\
                                  i{}['key'] = '{}';\
                                  globals.push(i{});", id, id, id, id, id, id, global_key.as_str(), id).as_str());
    }    

    let mut src_vec: Vec<&[u8]> = Vec::new();
    let mut replace_vec: Vec<&[u8]> = Vec::new();

    let footer_string: String = get_footer();
    src_vec.push("{header}".as_bytes());
    src_vec.push("{base_url}".as_bytes());
    src_vec.push("{tr}".as_bytes());
    src_vec.push("{array_js}".as_bytes());
    src_vec.push("{footer}".as_bytes());
    replace_vec.push(header.as_bytes());
    replace_vec.push(state.base_url.as_bytes());
    replace_vec.push(tr.as_bytes());
    replace_vec.push(array_js.as_bytes());
    replace_vec.push(footer_string.as_bytes());

    let mut page_str: HoString = HoFile::read_file_bytes("web/edit_global.html");
    page_str = page_str.replace_bytes_vec(src_vec, replace_vec);
    let html: String = page_str.to_str().to_string().to_owned();
    res.set_sized_body(Cursor::new(html));
    return res;
}

